package models

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"cvevulner/common"

	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
)

type OpenSaId struct {
	Id int64
}

func QueryYamlData(ge *GitOpenEuler, colName ...string) error {
	o := orm.NewOrm()
	err := o.Read(ge, colName...)
	return err
}

// insert data
func InsertYamlData(ge *GitOpenEuler) (int64, error) {
	o := orm.NewOrm()
	id, err := o.Insert(ge)
	return id, err
}

func UpdateYamlData(ge *GitOpenEuler, fields ...string) error {
	o := orm.NewOrm()
	_, err := o.Update(ge, fields...)
	return err
}

func QueryGitPackageInfo(ge *GitPackageInfo, colName ...string) error {
	o := orm.NewOrm()
	err := o.Read(ge, colName...)
	return err
}

// insert data
func InsertGitPackageInfo(ge *GitPackageInfo) (int64, error) {
	o := orm.NewOrm()
	id, err := o.Insert(ge)
	return id, err
}

func UpdateGitPackageInfo(ge *GitPackageInfo, fields ...string) error {
	o := orm.NewOrm()
	_, err := o.Update(ge, fields...)
	return err
}

func QueryOriginRepo(pkgName string) (GiteRepo, bool) {
	o := orm.NewOrm()
	var gr GiteRepo
	repoOrg, errx := common.GetRepoOrg()
	if errx != nil {
		logs.Error("QueryOriginRepo, GetRepoOrg, pkgName: ", pkgName,
			",Unable to get the organization corresponding to the repo, err: ", errx)
		return gr, false
	}
	err := o.Raw("select * from cve_gite_repo where path = ? and org_path = ? and status = ?",
		pkgName, repoOrg, 0).QueryRow(&gr)
	if err != nil {
		logs.Error("QueryOriginRepo, cve_gite_repo, "+
			"pkgName:", pkgName, ", repoOrg: ", repoOrg, ", No corresponding data")
		return gr, false
	} else {
		logs.Info("QueryOriginRepo, cve_gite_repo, "+
			"pkgName: ", pkgName, ", repoOrg: ", repoOrg, ", search successful")
		return gr, true
	}
}

func QueryOrgAllRepo(org string) []GiteRepo {
	o := orm.NewOrm()
	var gr []GiteRepo
	num, err := o.Raw("select * from cve_gite_repo where org_path = ? and status = ?", org, 0).QueryRows(&gr)
	if num == 0 {
		logs.Info("QueryOrgAllRepo, cve_gite_repo"+", repoOrg: ", org, ", No corresponding data, err: ", err)
		return gr
	} else {
		logs.Info("QueryOrgAllRepo, cve_gite_repo"+", repoOrg: ", org, ", search successful")
		return gr
	}
}

func QueryRepoMember(groupId int64, memberType string) ([]GiteRepoMember, bool) {
	o := orm.NewOrm()
	var grm []GiteRepoMember
	num, err := o.Raw("select * from cve_gite_repo_member where group_id = ?",
		groupId).QueryRows(&grm)
	if err != nil || num == 0 {
		logs.Info("QueryRepoMember, cve_gite_repo_member, "+
			"groupId: ", groupId, ",memberType: ", memberType, ", No corresponding data")
		return grm, false
	} else {
		logs.Info("QueryRepoMember, cve_gite_repo_member, "+
			"groupId: ", groupId, ",memberType: ", memberType, ", search successful")
		return grm, true
	}
}

func QueryRepoAllMaintainer(pkgName string) ([]GiteRepoMember, bool) {
	sia := SpecIssueAssigness{PackageName: pkgName, Status: 1}
	gr, okrg := QueryOriginRepo(pkgName)
	if !okrg || gr.RepoId == 0 {
		logs.Error("QueryRepoAllMaintainer, maintainer query failed, "+
			"pkgName: ", pkgName, ",okrg: ", okrg)
		specError := GetSpecIssueAssignee(&sia, "package_name", "status")
		if specError == nil && sia.Id > 0 {
			var grm []GiteRepoMember
			var grmr GiteRepoMember
			grmr.MemberName = sia.Assignee
			grm = append(grm, grmr)
			return grm, true
		}
		return nil, false
	}
	grm, okgrm := QueryRepoMember(gr.GroupId, "Maintainer")
	if !okgrm {
		logs.Error("QueryRepoMember, maintainer query failed, "+
			"pkgName: ", pkgName, ",gr.GroupId: ", gr.GroupId, ",okgrm: ", okgrm)
		specError := GetSpecIssueAssignee(&sia, "package_name", "status")
		if specError == nil && sia.Id > 0 {
			var grmr GiteRepoMember
			grmr.MemberName = sia.Assignee
			grm = append(grm, grmr)
			return grm, true
		}
		return nil, false
	}
	specError := GetSpecIssueAssignee(&sia, "package_name", "status")
	if specError == nil && sia.Id > 0 {
		assFlag := false
		for _, mt := range grm {
			if mt.MemberName == sia.Assignee {
				assFlag = true
				break
			}
		}
		if !assFlag {
			var grmr GiteRepoMember
			grmr.MemberName = sia.Assignee
			grm = append(grm, grmr)
		}
	}
	return grm, true
}

func QueryRepoMaintainer(pkgName string) (string, bool) {
	gr, okrg := QueryOriginRepo(pkgName)
	if !okrg || gr.RepoId == 0 {
		logs.Error("QueryRepoMaintainer, repo does not exist, err: ", okrg)
		return "", okrg
	}
	grm, okgrm := QueryRepoMember(gr.GroupId, "Maintainer")
	if !okgrm {
		logs.Error("QueryRepoMember, Maintainer does not exist, err: ", okrg)
		return "", okgrm
	}
	for _, g := range grm {
		if g.MemberName != "" && len(g.MemberName) > 1 {
			return g.MemberName, true
		}
	}
	return "", false
}

func QueryCveOpeneulerdata(ge *GitOpenEuler) bool {
	geErr := QueryYamlData(ge, "PackageName", "Version", "Status")
	if ge.GitId == 0 {
		logs.Error("QueryCveOpeneulerdata, There is no corresponding repo or version, ",
			ge.PackageName, ge.Version, ",geErr: ", geErr)
		return false
	}
	return true
}

func QueryCveOpeneulerDetaildataByName(pkgName, versions string) (goe GitPackageInfo, bl bool) {
	o := orm.NewOrm()
	err := error(nil)
	if versions == "" || len(versions) == 0 {
		err = o.Raw("select * from cve_git_package_info where package_name = ? and status = ? "+
			"order by detail_id desc limit 1", pkgName, 0).QueryRow(&goe)
	} else {
		err = o.Raw("select * from cve_git_package_info where package_name = ? and version = ? and status = ? "+
			"order by detail_id desc limit 1", pkgName, versions, 0).QueryRow(&goe)
	}
	if err != nil {
		logs.Error("QueryCveOpeneulerDetaildataByName, cve_git_package_info, pkgName: ", pkgName, ", versions: ", versions,
			", No corresponding data, err: ", err)
		return goe, false
	} else {
		logs.Info("QueryCveOpeneulerDetaildataByName, cve_git_package_info, pkgName: ", pkgName, ", versions: ", versions,
			", search successful")
		return goe, true
	}
}

func QueryCveOriginByIds(ids string) (OriginUpstream, bool) {
	o := orm.NewOrm()
	var orcve OriginUpstream
	err := o.Raw("select * from cve_origin_upstream where cve_un_ids = ?", ids).QueryRow(&orcve)
	if err != nil {
		return orcve, false
	} else {
		return orcve, true
	}
}

func CreateOriginCve(CveData common.CveOriginData, ou *OriginUpstream, od *OriginUpstreamDesc,
	ous *OriginUpstreamConfig, osi *OriginUpstreamImpact, osp *OriginUpstreamPoc, ose []*OriginUpstreamEvent,
	osv []*OriginUpstreamVulType, osf *OriginUpstreamFixSuggest, packageUrls []*OriginUpstreamPackageUrl) (Id int64, err error) {
	o := orm.NewOrm()
	errs := o.Begin()
	if errs == nil {
		ouse := OriginUpstream{Ids: ou.Ids}
		err := o.Read(&ouse, "Ids")
		if err == orm.ErrNoRows || err == orm.ErrMissPK {
			logs.Info("CreateOriginCve, Add data: ", ou)
			var num int64
			if num, err = o.Insert(ou); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream success, num:, cveNum", num, ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream failed, ou:", ou, ", err: ", err)
				o.Rollback()
				return 0, err
			}

			od.CveId = num
			lod := OriginUpstreamDesc{CveId: num}
			o.Delete(&lod, "CveId")
			if odnum, err := o.Insert(od); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream_desc success, num:", odnum, ", cveNum", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream_desc failed, ou:", ou, ", err: ", err)
				o.Rollback()
				return 0, err
			}

			if err := resetOriginPatch(&CveData, o, ou.Ids); err != nil {
				logs.Error("reset origin patch fail", err)
			}

			ous.CveId = num
			lous := OriginUpstreamConfig{CveId: num}
			err := o.Read(&lous, "CveId")
			if err == orm.ErrNoRows || err == orm.ErrMissPK {
				logs.Info("CreateOriginCve, cve_origin_upstream_config, "+
					"Data does not exist, cveId: ", num)
			} else {
				var lousc []OriginUpstreamConfigNode
				louscNum, err := o.Raw("select * from cve_origin_upstream_config_node where conf_id = ?",
					lous.ConfId).QueryRows(&lousc)
				if err != nil {
					logs.Info("CreateOriginCve, cve_origin_upstream_config_node, "+
						"Data does not exist, louscNum: ", louscNum)
				} else {
					for _, lsc := range lousc {
						ousnc := OriginUpstreamConfigNodeCpe{NodeId: lsc.NodeId}
						o.Delete(&ousnc, "NodeId")
					}
					ousn := OriginUpstreamConfigNode{ConfId: lous.ConfId}
					o.Delete(&ousn, "ConfId")
				}
				lousn := OriginUpstreamConfig{CveId: num}
				o.Delete(&lousn, "CveId")
			}
			if ousnum, err := o.Insert(ous); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream_config success, "+
					"ousnum:", ousnum, ", cveNum", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream_config failed,"+
					" ou:", ous, ", err: ", err)
				o.Rollback()
				return 0, err
			}
			if CveData.Configurations.Nodes != nil && len(CveData.Configurations.Nodes) > 0 {
				for _, nodes := range CveData.Configurations.Nodes {
					var Lnode OriginUpstreamConfigNode
					Lnode.Operator = nodes.Operator
					Lnode.ConfId = ous.ConfId
					if lousnum, err := o.Insert(&Lnode); err == nil {
						logs.Info("CreateOriginCve, insert cve_origin_upstream_config_node success, "+
							"lousnum:", lousnum, ", cveNum", ou.Ids)
					} else {
						logs.Error("CreateOriginCve, insert cve_origin_upstream_config_node failed, "+
							"Lnode:", Lnode, ", err: ", err)
						o.Rollback()
						return 0, err
					}
					if nodes.Cpe != nil && len(nodes.Cpe) > 0 {
						for _, nodCpe := range nodes.Cpe {
							var ouscnc OriginUpstreamConfigNodeCpe
							ouscnc.Cpe23Uri = nodCpe.Cpe23Uri
							ouscnc.NodeId = Lnode.NodeId
							ouscnc.CpeMatchString = nodCpe.CpeMatchString
							ouscnc.Vulnerable = nodCpe.Vulnerable
							if lousnumc, err := o.Insert(&ouscnc); err == nil {
								logs.Info("CreateOriginCve, insert cve_origin_upstream_config_node_cpe success, "+
									"lousnumc:", lousnumc, ", cveNum", ou.Ids)
							} else {
								logs.Error("CreateOriginCve, insert cve_origin_upstream_config_node_cpe failed, "+
									"ouscnc:", ouscnc, ", err: ", err)
								o.Rollback()
								return 0, err
							}
						}
					}
				}
			}

			if err := handleImpact(o, CveData.Impact, num, ou.Ids); err != nil {
				return 0, err
			}

			osp.CveId = num
			losp := OriginUpstreamPoc{CveId: num}
			errxxx := o.Read(&losp, "CveId")
			if errxxx == orm.ErrNoRows || errxxx == orm.ErrMissPK {
				logs.Info("CreateOriginCve, cve_origin_upstream_impact, Data does not exist, cveId: ", num)
			} else {
				lospd := OriginUpstreamPoc{CveId: num}
				o.Delete(&lospd, "CveId")
			}
			if ospnum, err := o.Insert(osp); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream_poc success, "+
					"ospnum:", ospnum, ", cveNum: ", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream_poc failed, "+
					"osp:", osp, ", err: ", err)
				o.Rollback()
				return 0, err
			}
			if len(ose) > 0 {
				losed := OriginUpstreamEvent{CveId: num}
				o.Delete(&losed, "CveId")
				for k := range ose {
					data := ose[k]
					data.CveId = num
				}
				if osenum, err := o.InsertMulti(len(ose), ose); err == nil {
					logs.Info("CreateOriginCve, insert cve_origin_upstream_event success, "+
						"osenum:", osenum, ", cveNum: ", ou.Ids)
				} else {
					logs.Error("CreateOriginCve, insert cve_origin_upstream_event failed, "+
						"ose:", ose, ", err: ", err)
					o.Rollback()
					return 0, err
				}
			}

			if len(packageUrls) > 0 {
				p := OriginUpstreamPackageUrl{CveId: num}
				o.Delete(&p, "CveId")

				for k := range packageUrls {
					packageUrls[k].CveId = num
				}

				if _, err = o.InsertMulti(len(packageUrls), packageUrls); err != nil {
					logs.Error("CreateOriginCve, insert cve_origin_upstream_package_url failed, "+
						"ose:", packageUrls, ", err: ", err)
					o.Rollback()
					return 0, err
				}
			}

			lousr := OriginUpstreamReference{CveId: num}
			o.Delete(&lousr, "CveId")
			if CveData.ReferenceData != nil && len(CveData.ReferenceData) > 0 {
				for _, ref := range CveData.ReferenceData {
					var lousrd OriginUpstreamReference
					lousrd.CveId = num
					lousrd.Url = ref.Url
					lousrd.SourceUrl = ref.SourceUrl
					lousrd.Refsource = ref.Refsource
					lousrd.Name = ref.Name
					tags := ""
					if ref.Tags != nil && len(ref.Tags) > 0 {
						for _, ta := range ref.Tags {
							tags = tags + string(ta) + ","
						}
						tags = tags[:len(tags)-1]
					}
					lousrd.Tags = tags
					if lousrdnum, err := o.Insert(&lousrd); err == nil {
						logs.Info("CreateOriginCve, insert cve_origin_upstream_reference success, "+
							"lousrdnum:", lousrdnum, ", cveNum: ", ou.Ids)
					} else {
						logs.Error("CreateOriginCve, insert cve_origin_upstream_reference failed, "+
							"lousrd:", lousrd, ", err: ", err)
						o.Rollback()
						return 0, err
					}
				}
			}
			if len(osv) > 0 {
				lousv := OriginUpstreamVulType{CveId: num}
				o.Delete(&lousv, "CveId")
				for k := range osv {
					typ := osv[k]
					typ.CveId = num
				}
				if osvnum, err := o.InsertMulti(len(osv), osv); err == nil {
					logs.Info("CreateOriginCve, insert cve_origin_upstream_vul_type success,"+
						" osvnum:", osvnum, ", cveNum: ", ou.Ids)
				} else {
					logs.Error("CreateOriginCve, insert cve_origin_upstream_vul_type failed, "+
						"osv:", osv, ", err: ", err)
					o.Rollback()
					return 0, err
				}
			}
			lousfs := OriginUpstreamFixSuggest{CveId: num}
			errxxsx := o.Read(&lousfs, "CveId")
			if errxxsx == orm.ErrNoRows || errxxsx == orm.ErrMissPK {
				logs.Info("CreateOriginCve, cve_origin_upstream_fix_suggest, Data does not exist, cveId: ", num)
			} else {
				var lousfst []OriginUpstreamFixSuggestRef
				louscNum, err := o.Raw("select * from cve_origin_upstream_fix_suggest_ref where fix_id = ?",
					lousfs.FixId).QueryRows(&lousfst)
				if err != nil {
					logs.Info("CreateOriginCve, cve_origin_upstream_fix_suggest_ref, Data does not exist, "+
						"louscNum: ", louscNum, "err: ", err)
				} else {
					for _, sc := range lousfst {
						lorfrt := OriginUpstreamFixSuggestRefTag{FixRefId: sc.FixRefId}
						o.Delete(&lorfrt, "FixRefId")
					}
					lo := OriginUpstreamFixSuggestRef{FixId: lousfs.FixId}
					o.Delete(&lo, "FixId")
				}
				lousfsx := OriginUpstreamFixSuggest{CveId: num}
				o.Delete(&lousfsx, "CveId")
			}
			osf.CveId = num
			if osfnum, err := o.Insert(osf); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream_fix_suggest success, "+
					"osfnum:", osfnum, ", cveNum: ", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream_fix_suggest failed, "+
					"osf:", osf, ", err: ", err)
				o.Rollback()
				return 0, err
			}
			if CveData.FixSuggest.References != nil && len(CveData.FixSuggest.References) > 0 {
				for _, refer := range CveData.FixSuggest.References {
					var lousfstr OriginUpstreamFixSuggestRef
					lousfstr.FixId = osf.FixId
					lousfstr.Name = refer.Name
					lousfstr.Refsource = refer.Refsource
					lousfstr.Url = refer.Url
					if osfstrnum, err := o.Insert(&lousfstr); err == nil {
						logs.Info("CreateOriginCve, insert cve_origin_upstream_fix_suggest_ref success, "+
							"osfstrnum:", osfstrnum, ", cveNum: ", ou.Ids)
					} else {
						logs.Error("CreateOriginCve, insert cve_origin_upstream_fix_suggest_ref failed, "+
							"lousfstr:", lousfstr, ", err: ", err)
						o.Rollback()
						return 0, err
					}
					if refer.Tags != nil && len(refer.Tags) > 0 {
						for _, refertag := range refer.Tags {
							var loufsrtg OriginUpstreamFixSuggestRefTag
							loufsrtg.FixRefId = lousfstr.FixRefId
							loufsrtg.Name = refertag
							if osfstgrnum, err := o.Insert(&loufsrtg); err == nil {
								logs.Info("CreateOriginCve, insert cve_origin_upstream_fix_suggest_ref_tag success, "+
									"osfstgrnum:", osfstgrnum, ", cveNum: ", ou.Ids)
							} else {
								logs.Error("CreateOriginCve, insert cve_origin_upstream_fix_suggest_ref_tag failed, "+
									"loufsrtg:", loufsrtg, ", err: ", err)
								o.Rollback()
								return 0, err
							}
						}
					}
				}
			}
			o.Commit()
		} else {
			if ouse.Source == CveOriginUpstreamSourceVtopia && ou.Source == CveOriginUpstreamSource7cai {
				return 0, errors.New("source not match")
			}

			logs.Info("update datas: ", ou)
			ou.CveId = ouse.CveId
			ou.Ids = ouse.Ids
			ou.Source = ouse.Source
			ou.CreateTime = ouse.CreateTime
			if num, err := o.Update(ou); err == nil {
				logs.Info("CreateOriginCve, Update cve_origin_upstream success, num: ", num, ", cveNum: ", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, Update cve_origin_upstream failed, ou:", ou, ", err: ", err)
				o.Rollback()
				return 0, err
			}

			if err := resetOriginPatch(&CveData, o, ou.Ids); err != nil {
				logs.Error("reset origin patch fail", err)
			}

			num := ouse.CveId
			od.CveId = num
			lod := OriginUpstreamDesc{CveId: num}
			o.Delete(&lod, "CveId")
			if odnum, err := o.Insert(od); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream_desc success, num:", odnum, ", cveNum: ", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream_desc failed, ou:", ou, ", err: ", err)
				o.Rollback()
				return 0, err
			}
			ous.CveId = num
			lous := OriginUpstreamConfig{CveId: num}
			err := o.Read(&lous, "CveId")
			if err == orm.ErrNoRows || err == orm.ErrMissPK {
				logs.Info("CreateOriginCve, cve_origin_upstream_config, Data does not exist, cveId: ", num)
			} else {
				var lousc []OriginUpstreamConfigNode
				louscNum, err := o.Raw("select * from cve_origin_upstream_config_node where conf_id = ?",
					lous.ConfId).QueryRows(&lousc)
				if err != nil {
					logs.Info("CreateOriginCve, cve_origin_upstream_config_node, Data does not exist,"+
						" louscNum: ", louscNum)
				} else {
					for _, lsc := range lousc {
						ousnc := OriginUpstreamConfigNodeCpe{NodeId: lsc.NodeId}
						o.Delete(&ousnc, "NodeId")
					}
					ousn := OriginUpstreamConfigNode{ConfId: lous.ConfId}
					o.Delete(&ousn, "ConfId")
				}
				lousn := OriginUpstreamConfig{CveId: num}
				o.Delete(&lousn, "CveId")
			}
			if ousnum, err := o.Insert(ous); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream_config success, "+
					"ousnum:", ousnum, ", cveNum: ", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream_config failed, "+
					"ou:", ous, ", err: ", err)
				o.Rollback()
				return 0, err
			}
			if CveData.Configurations.Nodes != nil && len(CveData.Configurations.Nodes) > 0 {
				for _, nodes := range CveData.Configurations.Nodes {
					var Lnode OriginUpstreamConfigNode
					Lnode.Operator = nodes.Operator
					Lnode.ConfId = ous.ConfId
					if lousnum, err := o.Insert(&Lnode); err == nil {
						logs.Info("CreateOriginCve, insert cve_origin_upstream_config_node success, "+
							"lousnum:", lousnum, ", cveNum: ", ou.Ids)
					} else {
						logs.Error("CreateOriginCve, insert cve_origin_upstream_config_node failed, "+
							"Lnode:", Lnode, ", err: ", err)
						o.Rollback()
						return 0, err
					}
					if nodes.Cpe != nil && len(nodes.Cpe) > 0 {
						for _, nodCpe := range nodes.Cpe {
							var ouscnc OriginUpstreamConfigNodeCpe
							ouscnc.Cpe23Uri = nodCpe.Cpe23Uri
							ouscnc.NodeId = Lnode.NodeId
							ouscnc.CpeMatchString = nodCpe.CpeMatchString
							ouscnc.Vulnerable = nodCpe.Vulnerable
							if lousnumc, err := o.Insert(&ouscnc); err == nil {
								logs.Info("CreateOriginCve, insert cve_origin_upstream_config_node_cpe success, "+
									"lousnumc:", lousnumc, ", cveNum: ", ou.Ids)
							} else {
								logs.Error("CreateOriginCve, insert cve_origin_upstream_config_node_cpe failed, "+
									"ouscnc:", ouscnc, ", err: ", err)
								o.Rollback()
								return 0, err
							}
						}
					}
				}
			}

			if err := handleImpact(o, CveData.Impact, ouse.CveId, ou.Ids); err != nil {
				return 0, err
			}

			osp.CveId = num
			losp := OriginUpstreamPoc{CveId: num}
			errxxx := o.Read(&losp, "CveId")
			if errxxx == orm.ErrNoRows || errxxx == orm.ErrMissPK {
				logs.Info("CreateOriginCve, cve_origin_upstream_impact, Data does not exist, cveId: ", num)
			} else {
				lospd := OriginUpstreamPoc{CveId: num}
				o.Delete(&lospd, "CveId")
			}
			if ospnum, err := o.Insert(osp); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream_poc success,"+
					" ospnum:", ospnum, ", cveNum: ", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream_poc failed, "+
					"osp:", osp, ", err: ", err)
				o.Rollback()
				return 0, err
			}
			if len(ose) > 0 {
				losed := OriginUpstreamEvent{CveId: num}
				o.Delete(&losed, "CveId")
				for k := range ose {
					data := ose[k]
					data.CveId = num
				}
				if osenum, err := o.InsertMulti(len(ose), ose); err == nil {
					logs.Info("CreateOriginCve, insert cve_origin_upstream_event success, "+
						"osenum:", osenum, ", cveNum: ", ou.Ids)
				} else {
					logs.Error("CreateOriginCve, insert cve_origin_upstream_event failed, "+
						"ose:", ose, ", err: ", err)
					o.Rollback()
					return 0, err
				}
			}
			lousr := OriginUpstreamReference{CveId: num}
			o.Delete(&lousr, "CveId")
			if CveData.ReferenceData != nil && len(CveData.ReferenceData) > 0 {
				for _, ref := range CveData.ReferenceData {
					var lousrd OriginUpstreamReference
					lousrd.CveId = num
					lousrd.Url = ref.Url
					lousrd.SourceUrl = ref.SourceUrl
					lousrd.Refsource = ref.Refsource
					lousrd.Name = ref.Name
					tags := ""
					if ref.Tags != nil && len(ref.Tags) > 0 {
						for _, ta := range ref.Tags {
							tags = tags + string(ta) + ","
						}
						tags = tags[:len(tags)-1]
					}
					lousrd.Tags = tags
					if lousrdnum, err := o.Insert(&lousrd); err == nil {
						logs.Info("CreateOriginCve, insert cve_origin_upstream_reference success, "+
							"lousrdnum:", lousrdnum, ", cveNum: ", ou.Ids)
					} else {
						logs.Error("CreateOriginCve, insert cve_origin_upstream_reference failed, "+
							"lousrd:", lousrd, ", err: ", err)
						o.Rollback()
						return 0, err
					}
				}
			}
			if len(osv) > 0 {
				lousv := OriginUpstreamVulType{CveId: num}
				o.Delete(&lousv, "CveId")
				for k := range osv {
					typ := osv[k]
					typ.CveId = num
				}
				if osvnum, err := o.InsertMulti(len(osv), osv); err == nil {
					logs.Info("CreateOriginCve, insert cve_origin_upstream_vul_type success, "+
						"osvnum:", osvnum, ", cveNum: ", ou.Ids)
				} else {
					logs.Error("CreateOriginCve, insert cve_origin_upstream_vul_type failed, "+
						"osv:", osv, ", err: ", err)
					o.Rollback()
					return 0, err
				}
			}

			if len(packageUrls) > 0 {
				p := OriginUpstreamPackageUrl{CveId: num}
				o.Delete(&p, "CveId")

				for k := range packageUrls {
					packageUrls[k].CveId = num
				}

				if _, err = o.InsertMulti(len(packageUrls), packageUrls); err != nil {
					logs.Error("CreateOriginCve, insert cve_origin_upstream_package_url failed, "+
						"ose:", packageUrls, ", err: ", err)
					o.Rollback()
					return 0, err
				}
			}
			lousfs := OriginUpstreamFixSuggest{CveId: num}
			osErr := o.Read(&lousfs, "CveId")
			if osErr == orm.ErrNoRows || osErr == orm.ErrMissPK {
				logs.Info("CreateOriginCve, cve_origin_upstream_fix_suggest, Data does not exist, cveId: ", num)
			} else {
				var lousfst []OriginUpstreamFixSuggestRef
				louscNum, err := o.Raw("select * from cve_origin_upstream_fix_suggest_ref where fix_id = ?",
					lousfs.FixId).QueryRows(&lousfst)
				if err != nil {
					logs.Info("CreateOriginCve, cve_origin_upstream_fix_suggest_ref, Data does not exist,"+
						" louscNum: ", louscNum, "err: ", err)
				} else {
					for _, sc := range lousfst {
						lorfrt := OriginUpstreamFixSuggestRefTag{FixRefId: sc.FixRefId}
						o.Delete(&lorfrt, "FixRefId")
					}
					lo := OriginUpstreamFixSuggestRef{FixId: lousfs.FixId}
					o.Delete(&lo, "FixId")
				}
				lousfsx := OriginUpstreamFixSuggest{CveId: num}
				o.Delete(&lousfsx, "CveId")
			}
			osf.CveId = num
			if osfnum, err := o.Insert(osf); err == nil {
				logs.Info("CreateOriginCve, insert cve_origin_upstream_fix_suggest success, "+
					"osfnum:", osfnum, ", cveNum: ", ou.Ids)
			} else {
				logs.Error("CreateOriginCve, insert cve_origin_upstream_fix_suggest failed, "+
					"osf:", osf, ", err: ", err)
				o.Rollback()
				return 0, err
			}
			if CveData.FixSuggest.References != nil && len(CveData.FixSuggest.References) > 0 {
				for _, refer := range CveData.FixSuggest.References {
					var lousfstr OriginUpstreamFixSuggestRef
					lousfstr.FixId = osf.FixId
					lousfstr.Name = refer.Name
					lousfstr.Refsource = refer.Refsource
					lousfstr.Url = refer.Url
					if osfstrnum, err := o.Insert(&lousfstr); err == nil {
						logs.Info("CreateOriginCve, insert cve_origin_upstream_fix_suggest_ref success, "+
							"osfstrnum:", osfstrnum, ", cveNum: ", ou.Ids)
					} else {
						logs.Error("CreateOriginCve, insert cve_origin_upstream_fix_suggest_ref failed, "+
							"lousfstr:", lousfstr, ", err: ", err)
						o.Rollback()
						return 0, err
					}
					if refer.Tags != nil && len(refer.Tags) > 0 {
						for _, refertag := range refer.Tags {
							var loufsrtg OriginUpstreamFixSuggestRefTag
							loufsrtg.FixRefId = lousfstr.FixRefId
							loufsrtg.Name = refertag
							if osfstgrnum, err := o.Insert(&loufsrtg); err == nil {
								logs.Info("CreateOriginCve, insert cve_origin_upstream_fix_suggest_ref_tag success, "+
									"osfstgrnum:", osfstgrnum, ", cveNum: ", ou.Ids)
							} else {
								logs.Error("CreateOriginCve, insert cve_origin_upstream_fix_suggest_ref_tag failed, "+
									"loufsrtg:", loufsrtg, ", err: ", err)
								o.Rollback()
								return 0, err
							}
						}
					}
				}
			}
			o.Commit()
		}
	} else {
		logs.Error("CreateOriginCve, Transaction creation failed, cveNum:", ou.CveNum)
		return 0, errs
	}
	return 0, nil
}

func clearOldImpact(o orm.Ormer, cveId int64, oldImpact OriginUpstreamImpact) {
	var losis []OriginUpstreamImpactScore
	losisNum, err := o.Raw("select * from cve_origin_upstream_impact_score where impact_id = ?",
		oldImpact.ImpactId).QueryRows(&losis)
	if err != nil {
		logs.Info("CreateOriginCve, cve_origin_upstream_impact_score, Data does not exist,"+
			" losi.ImpactId: ", oldImpact.ImpactId, ", err: ", err, ",losisNum: ", losisNum)
	} else {
		for _, sis := range losis {
			if sis.CvssV3 == 1 && sis.BaseMetricV3 == 1 {
				lousisv3 := OriginUpstreamImpactScoreV3{ScoreId: sis.ScoreId}
				o.Delete(&lousisv3, "ScoreId")
			}
			if sis.CvssV4 == 1 {
				lousisv4 := OriginUpstreamImpactScoreV4{ScoreId: sis.ScoreId}
				o.Delete(&lousisv4, "ScoreId")
			}
		}
		losisx := OriginUpstreamImpactScore{ImpactId: oldImpact.ImpactId}
		o.Delete(&losisx, "ImpactId")
	}
	losix := OriginUpstreamImpact{CveId: cveId}
	o.Delete(&losix, "CveId")
}

func saveNewImpact(o orm.Ormer, cveId int64, source string, impact common.CveImpact) error {
	osi := new(OriginUpstreamImpact)
	osi.CveId = cveId
	osi.Source = source
	if _, err := o.Insert(osi); err != nil {
		logs.Error("CreateOriginCve, insert cve_origin_upstream_impact failed,"+" Lnode:", osi, ", err: ", err)
		o.Rollback()
		return err
	}

	var lousist OriginUpstreamImpactScore
	lousist.ImpactId = osi.ImpactId
	lousist.Status = 1
	if impact.ContainsV3() {
		lousist.BaseMetricV3 = 1
		lousist.CvssV3 = 1
	}

	if impact.ContainsV4() {
		lousist.CvssV4 = 1
	}

	if _, err := o.Insert(&lousist); err != nil {
		logs.Error("CreateOriginCve, insert cve_origin_upstream_impact_score failed ", err)
		o.Rollback()
		return err
	}

	if impact.ContainsV3() {
		if err := saveCVSS3(o, lousist.ScoreId, impact); err != nil {
			return err
		}
	}

	if impact.ContainsV4() {
		if err := saveCVSS4(o, lousist.ScoreId, impact); err != nil {
			return err
		}
	}

	return nil
}

func saveCVSS3(o orm.Ormer, scoreId int64, impact common.CveImpact) error {
	var lousisv3 OriginUpstreamImpactScoreV3
	lousisv3.ScoreId = scoreId
	lousisv3.BaseScore = impact.BaseMetricV3.CvssV3.BaseScore
	lousisv3.VectorString = impact.BaseMetricV3.CvssV3.VectorString
	lousisv3.AttackComplexity = impact.BaseMetricV3.CvssV3.AttackComplexity
	lousisv3.AttackVector = impact.BaseMetricV3.CvssV3.AttackVector
	lousisv3.AvailabilityImpact = impact.BaseMetricV3.CvssV3.AvailabilityImpact
	lousisv3.BaseSeverity = impact.BaseMetricV3.CvssV3.BaseSeverity
	lousisv3.UserInteraction = impact.BaseMetricV3.CvssV3.UserInteraction
	lousisv3.PrivilegesRequired = impact.BaseMetricV3.CvssV3.PrivilegesRequired
	lousisv3.Version = impact.BaseMetricV3.CvssV3.Version
	lousisv3.ConfidentialityImpact = impact.BaseMetricV3.CvssV3.ConfidentialityImpact
	lousisv3.IntegrityImpact = impact.BaseMetricV3.CvssV3.IntegrityImpact
	lousisv3.Scope = impact.BaseMetricV3.CvssV3.Scope
	lousisv3.ImpactScore = impact.BaseMetricV3.ImpactScore
	lousisv3.ExploitabilityScore = impact.BaseMetricV3.ExploitabilityScore
	lousisv3.CveLevel = OpenEulerScoreProc(impact.BaseMetricV3.CvssV3.BaseScore)
	if _, err := o.Insert(&lousisv3); err != nil {
		logs.Error("CreateOriginCve, insert cve_origin_upstream_impact_score_v3 failed", err)
		o.Rollback()
		return err
	}

	return nil
}

func saveCVSS4(o orm.Ormer, scoreId int64, impact common.CveImpact) error {
	lousisv4 := OriginUpstreamImpactScoreV4{
		ScoreId: scoreId,
		Score:   impact.MetricV4.Score,
		Vector:  impact.MetricV4.Vector,
	}

	if _, err := o.Insert(&lousisv4); err != nil {
		o.Rollback()
		return err
	}

	return nil
}

func handleImpact(o orm.Ormer, newImpact map[string]common.CveImpact, cveId int64, cveNum string) error {
	var impacts []OriginUpstreamImpact
	_, err := o.QueryTable(&OriginUpstreamImpact{}).Filter("cve_id", cveId).All(&impacts)
	if err != nil {
		return err
	}

	for _, v := range impacts {
		clearOldImpact(o, cveId, v)
	}

	for source, v := range newImpact {
		if err = saveNewImpact(o, cveId, source, v); err != nil {
			logs.Error("saveNewImpact of %s failed:%s", cveNum, err.Error())
			return err
		}
	}

	return nil
}

func resetOriginPatch(cveData *common.CveOriginData, o orm.Ormer, oid string) error {
	if cveData == nil {
		return nil
	}

	delPatch := &OriginUpstreamPatch{OID: oid, CveNum: cveData.CveNum}
	_, _ = o.Delete(delPatch, "o_id", "cve_num")

	if cveData.UpdateType == "delete" {
		return nil
	}

	var patches []OriginUpstreamPatch
	for _, v := range cveData.Patch {
		patches = append(patches, OriginUpstreamPatch{
			OID:        oid,
			CveNum:     cveData.CveNum,
			Package:    v.Package,
			FixVersion: v.FixVersion,
			FixPatch:   v.FixPatch,
			BreakPatch: v.BreakPatch,
			Source:     v.Source,
			Branch:     v.Branch,
		})
	}

	bulk := len(patches)
	if len(patches) == 0 {
		return nil
	}

	o.Insert(&OriginUpstreamPatchFirstTime{
		CveNum:   cveData.CveNum,
		CreateAt: time.Now().Format(common.DATE_FORMAT),
	})

	_, err := o.InsertMulti(bulk, patches)

	return err
}

func QueryCveOriginPatchInfo(cveNum string) ([]OriginUpstreamPatch, error) {
	if cveNum == "" {
		return nil, nil
	}

	sql := "select * from cve_origin_upstream_patch where o_id = ? and fix_patch not like '%\"%' limit 100"
	o := orm.NewOrm()
	var res []OriginUpstreamPatch

	_, err := o.Raw(sql, cveNum).QueryRows(&res)
	if err != nil {
		return nil, err
	}

	return res, nil
}

func QueryCveOriginReference(cveNum string) ([]OriginUpstreamReference, error) {
	if cveNum == "" {
		return nil, nil
	}
	o := orm.NewOrm()
	var id struct {
		CveId int64 `orm:"column(cve_id)"`
	}
	_ = o.Raw("select cve_id from cve_origin_upstream where cve_num = ? order by cve_id desc", cveNum).QueryRow(&id)
	if id.CveId == 0 {
		return nil, nil
	}

	sql := "select * from cve_origin_upstream_reference where cve_id = ? and url not like '%\"%' limit 100"
	var res []OriginUpstreamReference

	_, err := o.Raw(sql, id.CveId).QueryRows(&res)
	if err != nil {
		return nil, err
	}

	return res, nil
}

func QueryCveOrigin(cveNum, typ string) bool {
	sql := "select * from cve_origin_upstream where (cve_num = ? or cve_un_ids = ?) and update_type = ?"
	o := orm.NewOrm()
	var res OriginUpstream
	err := o.Raw(sql, cveNum, cveNum, typ).QueryRow(&res)
	if err != nil {
		return false
	}

	return true
}

func QueryCveOriginByNum(cveNum string) (OriginUpstream, error) {
	o := orm.NewOrm()
	ou := OriginUpstream{CveNum: cveNum}
	err := o.Read(&ou, "CveNum")

	return ou, err
}

func FilterOldData(cve string) bool {
	sql := "select * from cve_origin_upstream where cve_num = ?"
	o := orm.NewOrm()
	var res OriginUpstream
	err := o.Raw(sql, cve).QueryRow(&res)
	if err != nil {
		return false
	}
	if res.Credibility > 3 && res.CveId <= 20557 {
		return true
	}

	return false
}

func QueryCveErrorInfo(issueStatus int8, startDate, endDate string) ([]IssueTemplate, bool) {
	o := orm.NewOrm()
	var it []IssueTemplate
	var num int64
	var err error
	if startDate != "" {
		num, err = o.Raw("select cve_num,error_description,create_time from cve_issue_template "+
			"where status > ? and create_time >= ? and create_time <= ?",
			issueStatus, startDate, endDate).QueryRows(&it)
	} else {
		num, err = o.Raw("select cve_num,error_description,create_time from cve_issue_template "+
			"where status > ? and create_time <= ?", issueStatus, endDate).QueryRows(&it)
	}
	if err != nil || num == 0 {
		logs.Error("QueryCveErrorInfo, ", issueStatus, startDate, endDate,
			", cve_issue_template, No corresponding data")
		return it, false
	}

	return it, true
}

func GetOpengaussYaml(opy *OpenGussYaml, colName ...string) (err error) {
	o := orm.NewOrm()
	packageName := "%" + opy.PackageName + "%"
	if len(opy.PackageName) < 1 && len(opy.Version) < 1 {
		logs.Error("openGauss request query parameters: ", *opy)
		return errors.New("openGauss request query parameters error")
	}

	if len(opy.PackageName) > 1 && len(opy.Version) > 0 {
		err = o.Raw(
			"select * from cve_open_guss_yaml where package_name like ? and version = ? "+
				"order by id asc limit ?", packageName, opy.Version, 1,
		).QueryRow(opy)
	} else {
		err = o.Raw(
			"select * from cve_open_guss_yaml where package_name like ? order by id asc limit ?", packageName, 1,
		).QueryRow(opy)
	}

	return
}

func GetOpengaussYamlAll(opy *OpenGussYaml) (msy []OpenGussYaml, err error) {
	o := orm.NewOrm()
	packageName := "%" + opy.PackageName + "%"
	if len(opy.PackageName) < 1 && len(opy.Version) < 1 {
		logs.Error("GetOpengaussYamlAll, openGauss request query parameters: ", *opy)
		return msy, errors.New("openGauss request query parameters error")
	}

	if len(opy.PackageName) > 1 && len(opy.Version) > 0 {
		verStr := "("
		verList := strings.Split(opy.Version, ",")
		for _, ver := range verList {
			verStr += "'" + ver + "',"
		}
		verStr = verStr[:len(verStr)-1] + ")"
		sql := fmt.Sprintf(`select * from cve_open_guss_yaml where package_name like '%s' 
and version in %s group by repo_name order by id asc`, packageName, verStr)
		_, err = o.Raw(sql).QueryRows(&msy)
	} else {
		_, err = o.Raw("select * from cve_open_guss_yaml where package_name like ? "+
			"order by id asc", packageName).QueryRows(&msy)
	}

	return
}

func GetMindSporeYaml(opy *MindSporeYaml, colName ...string) (err error) {
	o := orm.NewOrm()
	if len(opy.PackageName) < 1 && len(opy.Version) < 1 {
		logs.Error("Mindspore request query parameters: ", *opy)
		return errors.New("Mindspore request query parameters error")
	}

	if len(opy.PackageName) > 1 && len(opy.Version) > 0 {
		err = o.Raw(
			"select * from cve_mind_spore_yaml where package_name = ? and version = ? "+
				"order by id asc limit ?", opy.PackageName, opy.Version, 1,
		).QueryRow(opy)
		return
	} else {
		err = o.Raw(
			"select * from cve_mind_spore_yaml where package_name = ? order by id asc limit ?", opy.PackageName, 1,
		).QueryRow(opy)
	}

	return
}

func GetMindSporeYamlForids(ids []string) (msy []MindSporeYaml, err error) {
	if len(ids) == 0 {
		return
	}
	o := orm.NewOrm()
	_, err = o.Raw(
		fmt.Sprintf("select * from cve_mind_spore_yaml where id in (%s) order by id asc", strings.Join(ids, ",")),
	).QueryRows(&msy)

	return
}

func GetMindSporeYamlAll(opy *MindSporeYaml) (msy []MindSporeYaml, err error) {
	o := orm.NewOrm()
	if len(opy.PackageName) < 1 && len(opy.Version) < 1 {
		logs.Error("GetMindSporeYamlAll, Mindspore request query parameters: ", *opy)
		return msy, errors.New("Mindspore request query parameters error")
	}

	if len(opy.PackageName) > 1 && len(opy.Version) > 0 {
		verStr := "("
		verList := strings.Split(opy.Version, ",")
		for _, ver := range verList {
			verStr += "'" + ver + "',"
		}
		verStr = verStr[:len(verStr)-1] + ")"
		sql := fmt.Sprintf(
			`select * from cve_mind_spore_yaml where package_name = '%s' and version in %s group by repo_name order by id asc`,
			opy.PackageName, verStr)
		_, err = o.Raw(sql).QueryRows(&msy)
	} else {
		_, err = o.Raw("select * from cve_mind_spore_yaml where package_name = ? "+
			"order by id asc", opy.PackageName).QueryRows(&msy)
	}

	return
}

func InsertOriginCveRecord(our *OriginUpstreamRecord) error {
	o := orm.NewOrm()
	_, err := o.Insert(our)

	return err
}

func DeleteOriginCveRecord(beforeDate string) {
	o := orm.NewOrm()
	if err := o.Raw(
		"delete from cve_origin_upstream_record where create_time < ?", beforeDate,
	).QueryRow(); err != nil {
		logs.Info("DeleteOriginCveRecord", err)
	}
}

func GetOpenLookengYaml(opy *OpenLookengYaml, colName ...string) (err error) {
	o := orm.NewOrm()
	if len(opy.PackageName) < 1 && len(opy.Version) < 1 {
		logs.Error("OpenLooKeng request query parameters: ", *opy)
		return errors.New("OpenLooKeng request query parameters error")
	}

	if len(opy.PackageName) > 1 && len(opy.Version) > 0 {
		err = o.Raw(
			"select * from cve_open_lookeng_yaml where package_name = ? and version = ? "+
				"order by id asc limit ?", opy.PackageName, opy.Version, 1,
		).QueryRow(opy)

	} else {
		err = o.Raw(
			"select * from cve_open_lookeng_yaml where package_name = ? order by id asc limit ?", opy.PackageName, 1,
		).QueryRow(opy)
	}

	return
}

func GetOpenLookengYamlAll(opy *OpenLookengYaml) (msy []OpenLookengYaml, err error) {
	o := orm.NewOrm()
	if len(opy.PackageName) < 1 && len(opy.Version) < 1 {
		logs.Error("GetOpenLookengYamlAll, openLookeng request query parameters: ", *opy)
		return msy, errors.New("openLookeng request query parameters error")
	}

	if len(opy.PackageName) > 1 && len(opy.Version) > 0 {
		verStr := "("
		verList := strings.Split(opy.Version, ",")
		for _, ver := range verList {
			verStr += "'" + ver + "',"
		}
		verStr = verStr[:len(verStr)-1] + ")"
		sql := fmt.Sprintf(`select * from cve_open_lookeng_yaml where package_name = '%s'  
and version in %s group by repo_name order by id asc`, opy.PackageName, verStr)
		_, err = o.Raw(sql).QueryRows(&msy)
	} else {
		_, err = o.Raw(
			"select * from cve_open_lookeng_yaml where package_name = ? order by id asc", opy.PackageName,
		).QueryRows(&msy)
	}

	return
}
